一、表單元件常用的屬性
二、按鈕元件:QBtn
三、文字輸入:QInput
四、核取方塊 (QCheckbox、QRadio)
五、下拉選單:(QSelect)
六、檔案選擇欄位:(QFile)
七、總結
disable
相當於原生HTML的disable
無法進行欄位的資料選取和修改
input-class的樣式也會稍微改變
readonly
可以選取資料,但是無法修改資料
不會改變input-class的樣式
v-model
元件呈現的資料綁定
範例示意:
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md column" style="max-width: 300px">
<q-input input-class="input rounded-borders" borderless v-model="text" hint="Readonly" :dense="dense" disable></q-input>
<q-input input-class="input rounded-borders" borderless v-model="text" hint="Readonly" :dense="dense" readonly></q-input>
</div>
</div>
</template>
<script>
export default {
data () {
return {
text: '123'
}
}
}
</script>
<style lang="scss" scoped>
.input {
padding: 0 7px;
border: 1px solid #333;
}
</style>
用途相當廣泛的元件,經常用於
Quasar has a component called QBtn which is a button with a few extra useful features.
https://quasar.dev/vue-components/button#QBtn-API
<div class="q-pa-md q-gutter-sm">
<q-btn unelevated type="a" href="start/pick-quasar-flavour" label="作為超連結" color="red-7"></q-btn>
</div>
<div class="q-pa-md q-gutter-sm">
<q-btn unelevated :to="{ name: 'routeName' }" label="前端路由行為" color="green-7"></q-btn>
</div>
<div class="q-pa-md q-gutter-sm">
<q-btn unelevated @click="someMethod" label="資料操作行為" color="blue-7"></q-btn>
</div>
QBtn的display是inline-block,預設寬度會根據內容改變
可以使用第二十一天談到的Flex Grid,設定寬度比例
以及第二十三天的class="full-width"設定與按鈕外的容器等寬
<div class="q-pa-md">
<div class="row q-col-gutter-sm">
<div class="col-12 col-sm-4">
<q-btn class="full-width" unelevated type="a" href="start/pick-quasar-flavour" label="作為超連結" color="red-7"></q-btn>
</div>
<div class="col-12 col-sm-4">
<q-btn class="full-width" unelevated label="前端路由行為" color="green-7"></q-btn>
</div>
<div class="col-12 col-sm-4">
<q-btn class="full-width" unelevated @click="someMethod" label="資料操作行為" color="blue-7"></q-btn>
</div>
</div>
</div>
用於輸入文字的欄位
The QInput component is used to capture text input from the user. It uses v-model, similar to a regular input. It has support for errors and validation, and comes in a variety of styles, colors, and types.
https://quasar.dev/vue-components/input
除了一般的text,還包括了textarea和number
<div class="q-pa-md" style="max-width: 300px">
<div class="q-gutter-md">
<q-input
outlined
v-model="phone"
label="phone"
></q-input>
<q-input
type="number"
outlined
v-model="number"
label="number"
></q-input>
<q-input
type="textarea"
outlined
v-model="textarea"
label="textarea"
></q-input>
</div>
</div>
Quasar提供了很多預設的樣式
如果不喜歡的話,可以使用borderless屬性,另外使用class與input-class自訂樣式
https://quasar.dev/vue-components/input
<template>
<div id="q-app">
<div class="q-pa-md">
<div class="q-gutter-y-md column" style="width: 300px; max-width: 100%">
<q-toolbar class="q-pa-sm bg-primary text-white rounded-borders">
<q-btn round dense flat icon="menu" class="q-mr-xs"></q-btn>
<q-avatar class="gt-xs">
<img src="https://cdn.quasar.dev/logo/svg/quasar-logo.svg">
</q-avatar>
<q-space></q-space>
<q-input dense borderless v-model="text" class="text-input" class="q-ml-md">
<template v-slot:append>
<q-icon v-if="text === ''" name="search"></q-icon>
<q-icon v-else name="clear" class="cursor-pointer" @click="text = ''"></q-icon>
</template>
</q-input>
</q-toolbar>
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
text: ''
}
}
}
</script>
<style lang="scss" scoped>
.text-input {
margin: 3px 12px;
padding: 5px;
background: white;
border-radius: 10px;
}
</style>
QInput 前後可以透過<template v-slot:append>加入ICON
<q-input outlined bottom-slots v-model="text" label="Label" counter :dense="dense">
<template v-slot:prepend>
<q-icon name="place" />
</template>
<template v-slot:append>
<q-icon name="close" @click="text = ''" class="cursor-pointer" />
</template>
</q-input>
「clear屬性」自帶清除內容的功能
<q-input
clearable
clear-icon="close"
outlined
v-model="text"
label="Label"
/>
「mask屬性」可以用於特定格式的文字輸入
<div class="q-pa-md" style="max-width: 300px">
<div class="q-gutter-md">
<q-input
outlined
v-model="phone"
label="phone"
mask="####-### ###"
fill-mask="#"
></q-input>
</div>
</div>
搭配QForm,可以做簡單的格式校驗
https://quasar.dev/vue-components/form
<template>
<div class="q-pa-md" style="max-width: 400px">
<q-form
@submit="onSubmit"
@reset="onReset"
class="q-gutter-md"
>
<q-input
filled
v-model="name"
label="Your name *"
hint="Name and surname"
lazy-rules
:rules="[ val => val && val.length > 0 || 'Please type something']"
/>
<q-input
filled
type="number"
v-model="age"
label="Your age *"
lazy-rules
:rules="[
val => val !== null && val !== '' || 'Please type your age',
val => val > 0 && val < 100 || 'Please type a real age'
]"
/>
<q-toggle v-model="accept" label="I accept the license and terms" />
<div>
<q-btn label="Submit" type="submit" color="primary"/>
<q-btn label="Reset" type="reset" color="primary" flat class="q-ml-sm" />
</div>
</q-form>
</div>
</template>
<script>
export default {
data () {
return {
name: null,
age: null,
accept: false
}
},
methods: {
onSubmit () {
if (this.accept !== true) {
this.$q.notify({
color: 'red-5',
textColor: 'white',
icon: 'warning',
message: 'You need to accept the license and terms first'
})
}
else {
this.$q.notify({
color: 'green-4',
textColor: 'white',
icon: 'cloud_done',
message: 'Submitted'
})
}
},
onReset () {
this.name = null
this.age = null
this.accept = false
}
}
}
</script>
常用於某組資料的多選
或者類似加入會員的同意條款選項
The QCheckbox component is another basic element for user input. You can use this to supply a way for the user to toggle an option.
https://quasar.dev/vue-components/checkbox
多選的v-model要指向同一個data陣列變數
<template>
<div class="q-pa-md">
<div class="q-gutter-sm">
<q-checkbox v-model="selection" val="teal" label="Teal" color="teal" />
<q-checkbox v-model="selection" val="orange" label="Orange" color="orange" />
<q-checkbox v-model="selection" val="red" label="Red" color="red" />
<q-checkbox v-model="selection" val="cyan" label="Cyan" color="cyan" />
</div>
<div class="q-px-sm">
The model data: <strong>{{ selection }}</strong>
</div>
</div>
</template>
<script>
export default {
data () {
return {
selection: [ 'teal', 'red' ]
}
}
}
</script>
單一選項的勾選狀態,data變數的值為true或false
<template>
<div class="q-pa-md">
<div class="q-gutter-sm">
<q-checkbox
v-model="customModel"
color="secondary"
label="Do you agree with the terms & conditions?"
></q-checkbox>
</div>
<div class="q-px-sm">
The model data: <strong>'{{ customModel }}'</strong>
</div>
</div>
</template>
<script>
export default {
data () {
return {
customModel: false
}
}
}
</script>
相對於Checkbox,用於某組資料的單選
The QRadio component is another basic element for user input. You can use this to supply a way for the user to pick an option from multiple choices.
v-model要指向同一個data變數
<template>
<div class="q-pa-md">
<div class="q-gutter-sm">
<q-radio v-model="color" val="teal" label="Teal" color="teal" />
<q-radio v-model="color" val="orange" label="Orange" color="orange" />
<q-radio v-model="color" val="red" label="Red" color="red" />
<q-radio v-model="color" val="cyan" label="Cyan" color="cyan" />
</div>
<div class="q-gutter-sm">
<q-radio keep-color v-model="color" val="teal" label="Teal" color="teal" />
<q-radio keep-color v-model="color" val="orange" label="Orange" color="orange" />
<q-radio keep-color v-model="color" val="red" label="Red" color="red" />
<q-radio keep-color v-model="color" val="cyan" label="Cyan" color="cyan" />
</div>
<div class="q-px-sm q-mt-sm">
Your selection is: <strong>{{ color }}</strong>
</div>
</div>
</template>
<script>
export default {
data () {
return {
color: 'cyan'
}
}
}
</script>
具有強大篩選功能的單選或下拉選單
The QSelect component has two types of selection: single or multiple. This component opens up a menu for the selection list and action. A filter can also be used for longer lists.
https://quasar.dev/vue-components/select
其中QSelect的選單選項格式允許:
<template>
<div class="q-pa-md" style="max-width: 300px">
<div class="q-gutter-md">
<q-badge color="secondary" multi-line>
Model: "{{ model }}"
</q-badge>
<q-select filled v-model="model" :options="options" label="Standard" />
</div>
</div>
</template>
<script>
export default {
data () {
return {
model: null,
options: [
'Google', 'Facebook', 'Twitter', 'Apple', 'Oracle'
]
}
}
}
</script>
<template>
<div class="q-pa-md" style="max-width: 300px">
<div class="q-gutter-md">
<q-badge color="secondary" multi-line>
Model: "{{ model }}"
</q-badge>
<q-select filled v-model="model" :options="options" label="Standard" />
</div>
</div>
</template>
<script>
export default {
data () {
return {
model: null,
options: [
{
label: 'Google',
value: 'Google',
description: 'Search engine',
category: '1'
},
{
label: 'Facebook',
value: 'Facebook',
description: 'Social media',
category: '1'
},
{
label: 'Twitter',
value: 'Twitter',
description: 'Quick updates',
category: '2'
},
{
label: 'Apple',
value: 'Apple',
description: 'iStuff',
category: '2'
},
{
label: 'Oracle',
value: 'Oracle',
disable: true,
description: 'Databases',
category: '3'
}
]
}
}
}
</script>
要注意的是
如果選項是JSON格式
至少要包含「label」和「value」
label是顯示在QSelect上面的文字,value是代表這個選項的值
此時v-model預設的格式,會是整個選項的JSON格式
{ label: 'Test', value: 0 }
如果你希望v-model的格式,是JSON選項的value,在QSelect顯示label
使用emit-value + map-options 屬性
<q-select
filled
v-model="model"
:options="options"
label="Standard"
emit-value
map-options
/>
若要使用QSelect的篩選功能
需要設定「@filter」、「use-input」、「hide-selected」
<template>
<div class="q-pa-md">
<div class="q-gutter-md row">
<q-select
filled
v-model="model"
use-input
hide-selected
fill-input
input-debounce="0"
:options="options"
@filter="filterFn"
hint="Basic filtering"
style="width: 250px; padding-bottom: 32px"
>
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey">
No results
</q-item-section>
</q-item>
</template>
</q-select>
</div>
</div>
</template>
<script>
const stringOptions = [
'Google', 'Facebook', 'Twitter', 'Apple', 'Oracle'
]
export default {
data () {
return {
model: null,
options: stringOptions
}
},
methods: {
filterFn (val, update, abort) {
update(() => {
const needle = val.toLowerCase()
this.options = stringOptions.filter(v => v.toLowerCase().indexOf(needle) > -1)
})
}
}
}
</script>
有寫過檔案上傳的人應該知道
\原生的type=file,是不能使用v-model
QInput也是,不能使用v-model
Do NOT use a v-model when QInput is of type="file". Browser security policy does not allow a value to be set to such an input. As a result, you can only read it (attach an @input event), but not write it.
https://quasar.dev/vue-components/input
<template>
<q-page class="flex flex-center q-gutter-md">
<div>
<q-input type="file" @change="selectData" borderless></q-input>
<q-img :src="dataUri" v-show="dataUri !== null" width="300px"></q-img>
</div>
</q-page>
</template>
<script>
export default {
name: 'PageIndex',
data () {
return {
file: null,
dataUri: null
}
},
methods: {
selectData (e) {
const reader = new FileReader()
this.file = e.target.files[0]
reader.readAsDataURL(this.file)
reader.onload = (e) => {
this.dataUri = e.target.result
}
}
}
}
</script>
你可使用QFile代替
QFile本身包含了@change => data 這段過程
QFile is a component which handles the user interaction for picking file(s).
https://quasar.dev/vue-components/file-picker
<template>
<q-page class="flex flex-center q-gutter-md">
<div style="width: 300px;">
<q-file stack-label="選擇檔案" label-color="white" input-class="text-white" class="bg-grey-9 q-pa-sm" borderless v-model="file" @input="selectData"></q-file>
<q-img :src="dataUri" v-show="dataUri !== null" width="300px"></q-img>
</div>
</q-page>
</template>
<script>
export default {
name: 'PageIndex',
data () {
return {
file: null,
dataUri: null
}
},
methods: {
selectData (file) {
const reader = new FileReader()
this.file = file
reader.readAsDataURL(this.file)
reader.onload = (e) => {
this.dataUri = e.target.result
}
}
}
}
</script>
今天大致介紹了比較常用表單元件
如果對其他的元件有興趣,可以參考Quasar的官方元件
明天接著介紹經常與表單搭配使用的Dialog